'use strict'

var STORAGE_KEY_REQUEST_HISTORY = 'debug.request.history';
var HISTORY_MAX_SIZE = 50;

var $widgets = {};
var $templates = {};
var token = null;
var requestHistories = {};

$(document).ready(function() {
    initWidgets();
    initEvents();
});

function initHistory() {
    var historyString = localStorage.getItem(STORAGE_KEY_REQUEST_HISTORY);
    if ( historyString ) {
        requestHistories = JSON.parse(historyString);
    }
    updateHistoryDisplay();
}

function saveHistory() {
    var historyString = JSON.stringify(requestHistories);
    localStorage.setItem(STORAGE_KEY_REQUEST_HISTORY, historyString);
}

function getSortedHistoryKeys() {
    return Object.keys(requestHistories).sort(function(key1, key2) {
        return Number(key1) - Number(key2);
    });
}

function addHistory(historyItem) {
    var now = new Date();
    var timestamp = now.getTime();
    historyItem.timestamp = timestamp;

    requestHistories[timestamp] = historyItem;

    var keys = getSortedHistoryKeys();
    if ( keys.length > HISTORY_MAX_SIZE ) {
        var removingHistoryItem = requestHistories[keys[0]];
        $widgets.historyContainer
            .find('[data-timestamp="' + removingHistoryItem.timestamp + '"]')
            .remove();
        delete requestHistories[keys[0]];
    }

    updateHistoryDisplay(historyItem);
    saveHistory();
}

function updateHistoryDisplay(historyItem) {
    if ( !historyItem ) {
        $widgets.historyContainer.find('.item').remove();
        var keys = getSortedHistoryKeys();
        keys.forEach(function(key) {
            var historyItem = requestHistories[key];
            updateHistoryDisplay(historyItem);
        });
    }
    else {
        var $historyItem = $templates.historyItem.clone(true);
        $historyItem.find('.url').text(historyItem.url);
        $historyItem.find('.method').text(historyItem.method);
        $historyItem.find('.status').text(historyItem.status);
        $historyItem.attr('data-timestamp', historyItem.timestamp);
        $widgets.historyContainer
            .find('.title')
            .after($historyItem);
    }
}

function initWidgets() {
    $widgets = {
        buttonLogin: $('.panel-login .btn-login'),
        inputUserName: $('.panel-login .input-username'),
        inputPassword: $('.panel-login .input-password'),
        inputToken: $('.panel-login .input-token'),
        inputUrl: $('.panel-request .input-url'),
        buttonGet: $('.panel-request .btn-get'),
        buttonPost: $('.panel-request .btn-post'),
        buttonFormatJSON: $('.panel-request .btn-format'),
        inputRequestContent: $('.panel-request .input-request-content'),
        inputResponseContent: $('.panel-request .input-response-content'),
        historyContainer: $('.panel-history .box-history'),
    };

    $templates.historyItem = $('.panel-history .box-history .item').remove();
    initHistory();
}

function initEvents() {
    $widgets.buttonLogin.click(login);
    $widgets.buttonGet.click(sendGet);
    $widgets.buttonPost.click(sendPost);
    $widgets.buttonFormatJSON.click(formatRequestContent);
    $widgets.historyContainer.on('dblclick', '.item', restoreHistoryItem);
}

function login(e) {
    disableAll(e);

    var user = {
        name: $widgets.inputUserName.val(),
        password: MD5($widgets.inputPassword.val())
    };
    
    var loginUrl = '/user/login';
    var loginRequest = new Request(loginUrl);
    loginRequest.postJSON({
        user: user
    }, function(result) {
        if ( !(result.successful) ) {
            alert('登录失败。' + JSON.stringify(result.error));
        }

        refreshToken(result.data.token);
    }, function(error) {
        alert('登录失败。' + JSON.stringify(error));
        console.log(error);
    });
}

function sendGet(e) {
    disableAll(e);

    $widgets.inputRequestContent.val('');
    var url = $widgets.inputUrl.val();
    var request = createRequest(url);

    request.getJSON(function(result) {
        var responseJSON = JSON.stringify(result);
        var formattedJSON = formatJSON(responseJSON, '    ');
        $widgets.inputResponseContent.val(formattedJSON);

        addHistory({
            url: url,
            method: 'GET',
            status: 'Successful',
            requestContent: '',
            responseContent: formattedJSON
        });
    }, function(result) {
        addHistory({
            url: url,
            method: 'GET',
            status: 'Failed',
            requestContent: '',
            responseContent: ''
        });
    });
}

function sendPost(e) {
    disableAll(e);

    var url = $widgets.inputUrl.val();
    var request = createRequest(url);
    var requestContent = $widgets.inputRequestContent.val();
    var requestData = JSON.parse(requestContent);

    request.postJSON(requestData, function(result) {
        var responseJSON = JSON.stringify(result);
        var formattedJSON = formatJSON(responseJSON, '    ');
        $widgets.inputResponseContent.val(formattedJSON);

        addHistory({
            url: url,
            method: 'POST',
            status: 'Successful',
            requestContent: requestContent,
            responseContent: formattedJSON
        });
    }, function(result) {
        addHistory({
            url: url,
            method: 'POST',
            status: 'Failed',
            requestContent: '',
            responseContent: ''
        });
    });
}

function formatRequestContent(e) {
    disableAll(e);

    var requestContent = $widgets.inputRequestContent.val();
    var formattedJSON = formatJSON(requestContent, '    ');

    $widgets.inputRequestContent.val(formattedJSON);
}

function restoreHistoryItem(e) {
    disableAll(e);

    $widgets.historyContainer
        .find('.item')
        .removeClass('active');

    $(this).addClass('active');

    var timestamp = $(this).attr('data-timestamp');
    var historyItem = requestHistories[timestamp];

    $widgets.inputUrl.val(historyItem.url);
    $widgets.inputRequestContent.val(historyItem.requestContent);
    $widgets.inputResponseContent.val(historyItem.responseContent);
}

function refreshToken(newToken) {
    token = newToken;
    $widgets.inputToken.val(token);
}

function createRequest(url) {
    if ( token ) {
        return new Request(url, {
            token: token
        });
    }

    return new Request(url);
}

